package net.minecraft.src;

import java.io.*;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Properties;
import java.util.List;
import java.util.Map;
import java.util.Random;

import net.minecraft.client.Minecraft;

public class mod_LF_GenericFurnitureMain extends BaseModMp
{
	//@MLProp public static boolean allowConsoleOut = false;
	//@MLProp public static boolean generateLogs = false;
	
	@MLProp public static int seattestentityid = 67;
	
	//@MLProp public static int softchairblockid = 206;
	//@MLProp public static int softchairitemid = 1501;
	//@MLProp public static int woodenchairblockid = 207;
	//@MLProp public static int woodenchairitemid = 1502;
	@MLProp public static int woodenstandblockid = 208;
	@MLProp public static int woodenstanditemid = 1503;
	@MLProp public static int woodentable2x1blockid = 209;
	@MLProp public static int woodentable2x1itemid = 1504;
	@MLProp public static int woodentable2x2blockid = 210;
	@MLProp public static int woodentable2x2itemid = 1505;
	@MLProp public static int woodentablehighblockid = 211;
	@MLProp public static int woodentablehighitemid = 1506;
	// @MLProp public static int woodenchairhighblockid = 212;
	// @MLProp public static int woodenchairhighitemid = 1507;
	@MLProp public static int woodentablelowblockid = 213;
	@MLProp public static int woodentablelowitemid = 1508;
	@MLProp public static int woodentable1x1blockid = 214;
	@MLProp public static int woodentable1x1itemid = 1509;
	// @MLProp public static int sofablockid = 215;
	// @MLProp public static int sofaitemid = 1510;
	// @MLProp public static int benchblockid = 216;
	// @MLProp public static int benchitemid = 1511;
	@MLProp public static int tvoffblockid = 217;
	@MLProp public static int tvitemid = 1512;
	@MLProp public static int tvonblockid = 218;
	@MLProp public static int softchairtestid = 1513;

	@MLProp public static int chnl1_ImageSize = 64;
	@MLProp public static int chnl1_Frames = 10;
	@MLProp public static int chnl2_ImageSize = 64;
	@MLProp public static int chnl2_Frames = 10;
	@MLProp public static int chnl3_ImageSize = 64;
	@MLProp public static int chnl3_Frames = 10;
	@MLProp public static int chnl4_ImageSize = 64;
	@MLProp public static int chnl4_Frames = 10;
	@MLProp public static int chnl5_ImageSize = 64;
	@MLProp public static int chnl5_Frames = 10;
	@MLProp public static int chnl6_ImageSize = 64;
	@MLProp public static int chnl6_Frames = 10;
	@MLProp public static int chnl7_ImageSize = 64;
	@MLProp public static int chnl7_Frames = 10;
	@MLProp public static int chnl8_ImageSize = 64;
	@MLProp public static int chnl8_Frames = 10;

	public static GuiScreen lastGuiOpen = null;
	public static Minecraft minecraft;
	
	private static boolean isPreAddons = true;
	private static boolean hasDeco1 = false;
	private static boolean hasTVPeriphs1 = false;
	private static boolean hasCarpetDrapes1 = false;
	private static boolean hasLights1 = false;
	
	public static int[] iconIndexes; 
	
	@Override
	public String getVersion() 
	{
		return "1.4 for MineCraft 1.2.3";
	}
	
	@Override
	public void handlePacket(Packet230ModLoader packet)
	{
		World world = ModLoader.getMinecraftInstance().theWorld;
		
		if(packet.dataInt[0] == 0)
		{
			if(world.getWorldInfo().getDimension() == packet.dataInt[1])
			{
				int i = packet.dataInt[2];
				int j = packet.dataInt[3];
				int k = packet.dataInt[4];
				
				LF_TileEntityTV tile = (LF_TileEntityTV)world.getBlockTileEntity(i, j, k);
				
				if(tile != null)
				{
					if((byte)packet.dataInt[5] == 0) 
					{
						tile.frame = 0;
						return;
					}
						
					tile.channel = (byte)packet.dataInt[5];
		    		tile.frame++;
		    		if(tile.frame > getChannelFrames(tile.channel))
		    			tile.frame = 1;
					
					world.scheduleBlockUpdate(i,j,k,blockTVOn.blockID,0);
				}
			}
		}
		else if(packet.dataInt[0] == 1)
		{
			EntityPlayer player;
			LF_EntitySeat seat;
			System.out.println("Packet gotten");
			
			for(int i=1; i<packet.dataInt.length; i+=2)
			{
				player = (EntityPlayer)getEntityByID(packet.dataInt[i]);
				seat = (LF_EntitySeat)getEntityByID(packet.dataInt[i+1]);
				
				player.mountEntity(seat);
			}
		}
	}
	
	public static int getChannelImageSize(int channel) {
		switch(channel) {
			case 1:
			{
				return chnl1_ImageSize;
			}
			case 2:
			{
				return chnl2_ImageSize;
			}
			case 3:
			{
				return chnl3_ImageSize;
			}
			case 4:
			{
				return chnl4_ImageSize;
			}
			case 5:
			{
				return chnl5_ImageSize;
			}
			case 6:
			{
				return chnl6_ImageSize;
			}
			case 7:
			{
				return chnl7_ImageSize;
			}
			case 8:
			{
				return chnl8_ImageSize;
			}
			default: 
			{
				return 0;
			}
		}
	}
	
	public static int getChannelFrames(int channel) {
		switch(channel) {
			case 1:
			{
				return chnl1_Frames;
			}
			case 2:
			{
				return chnl2_Frames;
			}
			case 3:
			{
				return chnl3_Frames;
			}
			case 4:
			{
				return chnl4_Frames;
			}
			case 5:
			{
				return chnl5_Frames;
			}
			case 6:
			{
				return chnl6_Frames;
			}
			case 7:
			{
				return chnl7_Frames;
			}
			case 8:
			{
				return chnl8_Frames;
			}
			default: 
			{
				return 0;
			}
		}
	}
	
	@Override
	public void addRenderer(Map map)
	{
		map.put(LF_EntitySeat.class, new LF_EntitySeatTestRenderer());
	}
	
    @Override
    public boolean onTickInGame(float f, Minecraft minecraft)
    {
        if(minecraft.currentScreen == null)
        {
            lastGuiOpen = null;
        }
        return true;
    }
    
    @Override
    public boolean onTickInGUI(float f, Minecraft minecraft, GuiScreen guiscreen)
    {
        if((guiscreen instanceof GuiContainerCreative) && !(lastGuiOpen instanceof GuiContainerCreative) && !minecraft.isMultiplayerWorld())
        {
        	System.out.println("Derp");
            Container container = ((GuiContainer)guiscreen).inventorySlots;
            List<ItemStack> list = ((ContainerCreative)container).itemList;
            
            for(int i=0; i<list.size(); i++)
            {
            	if((list.get(i).getItem() instanceof LF_ItemSpawner) || list.get(i).getItem() instanceof LF_ItemFurniture)
            	{
            		list.remove(i);
            		i--;
            	}
            }
            
            // TODO: MAKE SURE TO ADD THIS! for(int i=0; i<LF_ItemSpawner.itemNames.length; i++)
            for(int i=0; i<LF_ItemSpawner.numItems; i++)
            {
            	if(isPreAddons && ((i>=2 && i<=15) || i>=17)) continue;
            	if(i>=60 && i<=75) continue;
            	
            	if(!hasTVPeriphs1 && i>=23 && i<=27) continue;
            	if(!hasLights1 && i>=28 && i<=43) continue;
            	if(!hasDeco1 && i>=44 && i<=59) continue;
            	if(!hasCarpetDrapes1 && i>=76 && i<=107) continue;
            	
                list.add(new ItemStack(itemChairTest, 1, i));
            }
            
            // TODO: Remove this!
            list.add(new ItemStack(itemWoodenTableStand,1));
            list.add(new ItemStack(itemWoodenTable1x1,1));
            list.add(new ItemStack(itemWoodenTable2x1,1));
            list.add(new ItemStack(itemWoodenTable2x2,1));
            list.add(new ItemStack(itemWoodenTableLow,1));
            list.add(new ItemStack(itemWoodenTableHigh,1));
            
        }
        lastGuiOpen = guiscreen;
        return true;
    }
	
	@Override
	public void load()
	{
		setupIcons();
		setupIds();
		setupEntities();
		setupBlocks();

		ModLoader.setInGameHook(this, true, true);
		ModLoader.setInGUIHook(this, true, true);

		System.out.println("LF - Generic Furniture + TV: Courtesy of Lord Flower/HojoINC");
	}

	public void setupIcons()
	{
		iconIndexes = new int[LF_ItemSpawner.numItems];

		System.out.println(iconIndexes.length);

		iconIndexes[0] = ModLoader.addOverride("/gui/items.png", "/LordFlower/Items/LF_WoodenChair.png");
		iconIndexes[1] = ModLoader.addOverride("/gui/items.png", "/LordFlower/Items/LF_WoodenChairHigh.png");
		iconIndexes[16] = ModLoader.addOverride("/gui/items.png", "/LordFlower/Items/LF_SoftChair.png");
	}

	public void setupEntities()
	{
		ModLoader.registerEntityID(LF_EntitySeat.class, "LF_EntitySeatTest", seattestentityid);
		ModLoaderMp.registerNetClientHandlerEntity(LF_EntitySeat.class, seattestentityid);
	}

	public void setupBlocks()
	{    
        LF_TileEntityFurnitureRenderer WoodenTableStandRenderer= new  LF_TileEntityFurnitureRenderer(
        		"/LordFlower/TileEntityTextures/LF_WoodenTable.png",
        		LF_ModelWoodenTableStand.class);
        ModLoader.registerTileEntity(LF_TileEntityWoodenTableStand.class, "LF_Tile_WoodenTableStand", WoodenTableStandRenderer);   
        ModLoader.addName(itemWoodenTableStand, "Wooden Table Stand");
        ModLoader.addRecipe(new ItemStack(itemWoodenTableStand, 1), new Object[] {
        	" p ", "sss",
        	Character.valueOf('p'),
        	Block.planks,
        	Character.valueOf('s'),
        	Item.stick
        });

        LF_TileEntityFurnitureRenderer woodenTable2x1Renderer= new  LF_TileEntityFurnitureRenderer(
        		"/LordFlower/TileEntityTextures/LF_WoodenTable.png",
        		LF_ModelWoodenTable2x1.class);
        ModLoader.registerTileEntity(LF_TileEntityWoodenTable2x1.class, "LF_Tile_WoodenTable2x1", woodenTable2x1Renderer);   
        ModLoader.addName(itemWoodenTable2x1, "2x1 Wooden Table");
        ModLoader.addRecipe(new ItemStack(itemWoodenTable2x1, 1), new Object[] {
        	"tt",
        	Character.valueOf('t'),
        	itemWoodenTable1x1
        });
        
        LF_TileEntityFurnitureRenderer woodenTable2x2Renderer= new  LF_TileEntityFurnitureRenderer(
        		"/LordFlower/TileEntityTextures/LF_WoodenTable.png",
        		LF_ModelWoodenTable2x2.class);
        ModLoader.registerTileEntity(LF_TileEntityWoodenTable2x2.class, "LF_Tile_WoodenTable2x2", woodenTable2x2Renderer);   
        ModLoader.addName(itemWoodenTable2x2, "2x2 Wooden Table");
        ModLoader.addRecipe(new ItemStack(itemWoodenTable2x2, 1), new Object[] {
        	"tt",
        	Character.valueOf('t'),
        	itemWoodenTable2x1
        });
        
        LF_TileEntityFurnitureRenderer woodenTableHighRenderer= new  LF_TileEntityFurnitureRenderer(
        		"/LordFlower/TileEntityTextures/LF_WoodenTable.png",
        		LF_ModelWoodenTableHigh.class);
        ModLoader.registerTileEntity(LF_TileEntityWoodenTableHigh.class, "LF_Tile_WoodenTableHigh", woodenTableHighRenderer);   
        ModLoader.addName(itemWoodenTableHigh, "High Wooden Table");
        ModLoader.addRecipe(new ItemStack(itemWoodenTableHigh, 1), new Object[] {
        	"sts", "s s",
        	Character.valueOf('s'),
        	Item.stick,
        	Character.valueOf('t'),
        	itemWoodenTable1x1
        });
        
        LF_TileEntityFurnitureRenderer woodenTableLowRenderer= new  LF_TileEntityFurnitureRenderer(
        		"/LordFlower/TileEntityTextures/LF_WoodenTable.png",
        		LF_ModelWoodenTableLow.class);
        ModLoader.registerTileEntity(LF_TileEntityWoodenTableLow.class, "LF_Tile_WoodenTableLow", woodenTableLowRenderer);   
        ModLoader.addName(itemWoodenTableLow, "Low Wooden Table");
        ModLoader.addRecipe(new ItemStack(itemWoodenTableLow, 1), new Object[] {
        	"t",
        	Character.valueOf('t'),
        	itemWoodenTable1x1
        });
        
        LF_TileEntityFurnitureRenderer WoodenTable1x1Renderer= new  LF_TileEntityFurnitureRenderer(
        		"/LordFlower/TileEntityTextures/LF_WoodenTable.png",
        		LF_ModelWoodenTable1x1.class);
        ModLoader.registerTileEntity(LF_TileEntityWoodenTable1x1.class, "LF_Tile_WoodenTable1x1", WoodenTable1x1Renderer);   
        ModLoader.addName(itemWoodenTable1x1, "1x1 Wooden Table");
        ModLoader.addRecipe(new ItemStack(itemWoodenTable1x1, 1), new Object[] {
        	" t ", "sss",
        	Character.valueOf('t'),
        	itemWoodenTableStand,
        	Character.valueOf('s'),
        	Item.stick
        });
        
        LF_TileEntityTVRenderer TVRenderer= new  LF_TileEntityTVRenderer(
        		LF_ModelTVCase.class,
        		LF_ModelTVScreen.class);
        ModLoader.registerTileEntity(LF_TileEntityTV.class, "LF_Tile_TV", TVRenderer);   
        ModLoader.addName(itemTV, "TV");
        ModLoader.addRecipe(new ItemStack(itemTV, 1), new Object[] {
        	"ppp","prp","ggg",
        	Character.valueOf('p'),
        	Block.planks,
        	Character.valueOf('r'),
        	Item.redstone,
        	Character.valueOf('g'),
        	Block.glass
        });
        
        for(int i=0; i<LF_ItemSpawner.numItems; i++)
        {
        	if(isPreAddons && ((i>=2 && i<=15) || i>=17)) continue;
        	if(i>=60 && i<=75) continue;
        	
        	if(!hasTVPeriphs1 && i>=23 && i<=27) continue;
        	if(!hasLights1 && i>=28 && i<=43) continue;
        	if(!hasDeco1 && i>=44 && i<=59) continue;
        	if(!hasCarpetDrapes1 && i>=76 && i<=107) continue;
        	
        	ModLoader.addName(new ItemStack(itemChairTest, 1, i), LF_ItemSpawner.getDamageString(i));
        }
	}
	
	public Block makeBlock(Class blockClass, int id, Class tileClass, Material mat, float hard, String name)
	{
		try
		{
			return ((LF_BlockFurnitureBase)(blockClass.getConstructors()[0].newInstance(id, 0, tileClass, mat))).setHardness(hard).setBlockName(name);
		}
		catch(Exception e)
		{
			System.err.print(e);
			return null;
		}
	}
	
	public Item makeItem(int id, Block block, String filename, String name)
	{
		return new LF_ItemFurniture(id, (LF_BlockFurnitureBase)block).setIconIndex(ModLoader.addOverride("/gui/items.png", "/LordFlower/Items/" + filename)).setItemName(name);
	}
	
	public Item makeItem(int id, String filename, String name)
	{
		return new LF_ItemSpawner(id).setIconIndex(ModLoader.addOverride("/gui/items.png", "/LordFlower/Items/" + filename)).setItemName(name);
	}
	
	public Item makeItem(int id, String name)
	{
		return new LF_ItemSpawner(id).setIconIndex(0).setItemName(name);
	}
	
	public void setupIds()
	{
		blockWoodenTableStand = makeBlock(LF_BlockWoodenTableStand.class, woodenstandblockid, LF_TileEntityWoodenTableStand.class, Material.wood, 2.0f, "LF_Block_WoodenTableStand");
		itemWoodenTableStand = makeItem(woodenstanditemid, blockWoodenTableStand, "LF_WoodenTableStand.png", "LF_Item_WoodenTableStand");
		
		blockWoodenTable2x1 = makeBlock(LF_BlockWoodenTable2x1.class, woodentable2x1blockid, LF_TileEntityWoodenTable2x1.class, Material.wood, 2.0f, "LF_Block_WoodenTable2x1");
		itemWoodenTable2x1 = makeItem(woodentable2x1itemid, blockWoodenTable2x1, "LF_WoodenTable2x1.png", "LF_Item_WoodenTable2x1");
		
		blockWoodenTable2x2 = makeBlock(LF_BlockWoodenTable2x2.class, woodentable2x2blockid, LF_TileEntityWoodenTable2x2.class, Material.wood, 2.0f, "LF_Block_WoodenTable2x2");
		itemWoodenTable2x2 = makeItem(woodentable2x2itemid, blockWoodenTable2x2, "LF_WoodenTable2x2.png", "LF_Item_WoodenTable2x2");
		
		blockWoodenTableHigh = makeBlock(LF_BlockWoodenTableHigh.class, woodentablehighblockid, LF_TileEntityWoodenTableHigh.class, Material.wood, 2.0f, "LF_Block_WoodenTableHigh");
		itemWoodenTableHigh = makeItem(woodentablehighitemid, blockWoodenTableHigh, "LF_WoodenTableHigh.png", "LF_Item_WoodenTableHigh");
		
		blockWoodenTableLow = makeBlock(LF_BlockWoodenTableLow.class, woodentablelowblockid, LF_TileEntityWoodenTableLow.class, Material.wood, 2.0f, "LF_Block_WoodenTableLow");
		itemWoodenTableLow = makeItem(woodentablelowitemid, blockWoodenTableLow, "LF_WoodenTableLow.png", "LF_Item_WoodenTableLow");

		blockWoodenTable1x1 = makeBlock(LF_BlockWoodenTable1x1.class, woodentable1x1blockid, LF_TileEntityWoodenTable1x1.class, Material.wood, 2.0f, "LF_Block_WoodenTable1x1");
		itemWoodenTable1x1 = makeItem(woodentable1x1itemid, blockWoodenTable1x1, "LF_WoodenTable1x1.png", "LF_Item_WoodenTable1x1");
		
		blockTVOff = makeBlock(LF_BlockTVOff.class, tvoffblockid, LF_TileEntityTV.class, Material.wood, 2.0f, "LF_Block_TVOff");
		blockTVOn = makeBlock(LF_BlockTVOn.class, tvonblockid, LF_TileEntityTV.class, Material.wood, 2.0f, "LF_Block_TVOn");
		itemTV = makeItem(tvitemid, blockTVOff, "LF_TV.png", "LF_Item_TV");
		
		itemChairTest = makeItem(softchairtestid, "LF_Item_ChairTest");
	}

	public static void debugWrite(String string)
	{
		try
		{
			FileWriter fstream = new FileWriter("C:/Documents and Settings/Owner/AppData/Roaming/.minecraft/mods/DebugOut.txt");
			BufferedWriter out = new BufferedWriter(fstream);
			out.write(string);
			out.close();
		}
		catch(Exception e)
		{
			System.err.println(e);
		}
	}

	public static Object getPrivateField(Class class1, Object object, String strField)
	{
		try
		{
			Field field1 = class1.getDeclaredField(strField);
			field1.setAccessible(true);
			return field1.get(object);
			
		}
		catch(Exception e)
		{
			System.err.println("LF ERROR - Failed to retrieve private field");
			System.err.println(e);
		}
		return null;
	}
	public static void setPrivateField(Class class1, Object object, String strField, Object value)
	{
		try
		{
			Field field1 = class1.getDeclaredField(strField);
			field1.setAccessible(true);
			field1.set(object, value);
			
		}
		catch(Exception e)
		{
			System.err.println("LF ERROR - Failed to retrieve private field");
			System.err.println(e);
		}
	}
	public static Object invokePrivateMethod(Class class1, Object object, String strMethod, Class[] argTypes, Object[] args)
	{
		try
		{
			Method method1 = class1.getDeclaredMethod(strMethod, argTypes);
			method1.setAccessible(true);
			return method1.invoke(object,args);
			
		}
		catch(Exception e)
		{
			System.err.println("LF ERROR - Failed to invoke private method");
			System.err.println(e);
		}
		return null;
	}
	public static Entity getEntityByID(int id)
	{
		PlayerController controller = ModLoader.getMinecraftInstance().playerController;
		
		NetClientHandler netHandler = (NetClientHandler)getPrivateField(PlayerControllerMP.class,controller,"netClientHandler");
		Entity ent = (Entity)invokePrivateMethod(NetClientHandler.class,netHandler,"getEntityByID",
				new Class[]{int.class}, new Object[]{id});
		
		return ent;
	}
	
	// Blocks/Items
	public static Block blockWoodenTableStand;
	public static Item itemWoodenTableStand;
	public static Block blockWoodenTable2x1;
	public static Item itemWoodenTable2x1;
	public static Block blockWoodenTable2x2;
	public static Item itemWoodenTable2x2;
	public static Block blockWoodenTableHigh;
	public static Item itemWoodenTableHigh;
	public static Block blockWoodenTableLow;
	public static Item itemWoodenTableLow;
	public static Block blockWoodenTable1x1;
	public static Item itemWoodenTable1x1;
	public static Block blockTVOn;
	public static Block blockTVOff;
	public static Item itemTV;
	public static Item itemChairTest;
}